Regenerate registry API snapshot with organizations, impersonation, migration batches, admin user search, and event health endpoints - #358
Conversation
…igration batches, private facets, and admin event-health endpoints
|
📝 WalkthroughWalkthroughThe OpenAPI snapshot is regenerated to reflect several contract changes. The standalone New schemas include 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Merge activity
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ada314b264
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| summary: Search users by username prefix | ||
| description: Bounded username-prefix search over the GSI3 | ||
| USER_ALL#<first-letter> partition. Admin-gated, so the response carries | ||
| email, tier, and suspension status. An empty `q` returns no users. |
There was a problem hiding this comment.
Declare the user-search query parameter
The new admin user search is described as prefix-based and explicitly mentions q, but the OpenAPI operation does not declare any query parameters, so the generated client type is parameters.query?: never. Any typed caller for this endpoint cannot send ?q=alice; it will hit the empty-query case that the description says returns no users. The organization invite lookup has the same omission, so both user-search surfaces are effectively unusable from the generated client.
Useful? React with 👍 / 👎.
| - organizations | ||
| security: | ||
| - BearerAuth: [] | ||
| responses: |
There was a problem hiding this comment.
Add request bodies for organization mutations
This new POST /v0/organizations operation has no requestBody, which generated requestBody?: never in the typed client. The endpoint description requires the caller to submit at least the organization slug/display data to create or claim an org, so a typed client cannot make a valid request; the same missing-body pattern affects inviting members, changing roles, and editing the profile.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/engine/src/registry/openapi.snapshot.yaml (1)
1326-1360: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDeclare optional authentication on caller-relative facet reads.
Line 1326, Line 1358, Line 1384, and Line 1438 now document caller-relative/private-readable results, but these operations still do not model
BearerAuth. Generated clients/docs will not know auth is accepted for resolving private/latest reads.Contract shape to add upstream before regenerating
/v0/facets/{name}/latest-version: get: tags: - facets + security: + - {} + - BearerAuth: [] /v0/facets/{name}/versions/{version}: get: tags: - facets + security: + - {} + - BearerAuth: [] /v0/facets/{name}/{version}: get: tags: - facets + security: + - {} + - BearerAuth: [] /v0/facets/{name}/{version}/contents: get: tags: - facets + security: + - {} + - BearerAuth: []As per coding guidelines,
packages/engine/src/registry/openapi.snapshot.yamlis a vendored OpenAPI snapshot with a 4-line header; commit it but never hand-edit it.Also applies to: 1384-1389, 1438-1440
Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e43fc38c-0cdb-4f2b-bdb3-76410a36a5ed
⛔ Files ignored due to path filters (1)
packages/engine/src/registry/generated/registry-api.tsis excluded by!**/generated/**
📒 Files selected for processing (2)
packages/engine/src/registry/fixtures.tspackages/engine/src/registry/openapi.snapshot.yaml
| /v0/admin/users: | ||
| get: | ||
| operationId: getV0AdminUsers | ||
| summary: Search users by username prefix | ||
| description: Bounded username-prefix search over the GSI3 | ||
| USER_ALL#<first-letter> partition. Admin-gated, so the response carries | ||
| email, tier, and suspension status. An empty `q` returns no users. | ||
| tags: | ||
| - admin | ||
| security: | ||
| - BearerAuth: [] | ||
| responses: | ||
| "200": | ||
| description: Matching users | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/AdminUserListResponse" | ||
| "401": | ||
| description: Missing or invalid credentials | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/ApiErrorBody" | ||
| "403": | ||
| description: Caller is not an admin (or caller is suspended) | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/ApiErrorBody" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Expose the username-prefix query parameter.
Line 2228 documents admin search by prefix and Line 2542 documents invite lookup by query, but neither operation declares a q query parameter. Typed clients generated from this spec cannot pass the search term without escaping the contract.
Contract shape to add upstream before regenerating
/v0/admin/users:
get:
+ parameters:
+ - name: q
+ in: query
+ required: false
+ schema:
+ type: string
/v0/organizations/{slug}/lookup-user:
get:
parameters:
- schema:
type: string
in: path
name: slug
required: true
+ - name: q
+ in: query
+ required: false
+ schema:
+ type: stringAs per coding guidelines, packages/engine/src/registry/openapi.snapshot.yaml is a vendored OpenAPI snapshot with a 4-line header; commit it but never hand-edit it.
Also applies to: 2538-2572
Source: Coding guidelines
| /v0/organizations: | ||
| post: | ||
| operationId: postV0Organizations | ||
| summary: Create or claim an organization | ||
| description: Auto-creates the organization when the slug is unprotected and | ||
| within the per-user claim budget (1/24h, 5/30d); otherwise queues the | ||
| claim for admin review. Reserves the matching @<slug> scope and makes | ||
| the caller the founding Admin. | ||
| tags: | ||
| - organizations | ||
| security: | ||
| - BearerAuth: [] | ||
| responses: | ||
| "201": | ||
| description: Organization created | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/OrgDetailResponse" | ||
| "202": | ||
| description: Claim queued for admin review | ||
| "403": | ||
| description: Blocked or reserved name | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/ApiErrorBody" | ||
| "409": | ||
| description: Slug taken or a pending claim exists | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: "#/components/schemas/ApiErrorBody" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Add request bodies for mutating organization endpoints.
Line 2465 creates/claims an org without any slug/display-name input, Line 2607 invites a member without target/role input, Line 2642 changes a role without the new role, and Line 2709 updates a profile without profile fields. Generated clients will model these as empty POSTs.
Contract shape to add upstream before regenerating
/v0/organizations:
post:
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "`#/components/schemas/CreateOrganizationRequest`"
/v0/organizations/{slug}/members:
post:
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "`#/components/schemas/InviteOrgMemberRequest`"
/v0/organizations/{slug}/members/{userId}/role:
post:
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "`#/components/schemas/UpdateOrgMemberRoleRequest`"
/v0/organizations/{slug}/profile:
post:
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "`#/components/schemas/UpdateOrgProfileRequest`"As per coding guidelines, packages/engine/src/registry/openapi.snapshot.yaml is a vendored OpenAPI snapshot with a 4-line header; commit it but never hand-edit it.
Also applies to: 2606-2634, 2640-2673, 2708-2736
Source: Coding guidelines
|
Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance. |

Why
Regenerates the registry API types and OpenAPI snapshot from the latest upstream spec (
2026-06-23T20:50:08.809Z), picking up a significant set of new endpoints and schema changes.Details
Organizations
POST /v0/organizations), list (GET /v0/organizations), get by slug, list/invite/remove members, change member roles, edit profile, and accept/decline invitations.org-claimas a validqueue_typealongsideglobal-facet, and queue items includerequested_display_nameandrequested_slug.ownerfields onFacetSummary,VersionMetadata, andScopeRootResponseare now a discriminated union of{ kind: "org", slug }and{ kind: "user", username }instead of the previous user-onlyOwnerRef. The standaloneOwnerRefschema is removed.visibility("private" | "public") is now a required field onFacetSummaryandVersionMetadata.Private facets & caller-relative access
no-storecaching for private versions andlatestresolutions. The304 Not Modifiedresponses are removed from the metadata and contents operations.GET /v0/facets/countadded, returning an eventually-consistent count of live public facets.Admin impersonation
POST /v0/admin/users/{id}/impersonationvalidates a target (non-admin only) and returns the metadata the UI needs to drive impersonation viaX-Facet-Impersonate-User-Id. No token is minted.DELETE /v0/auth/impersonationis a stateless no-op (204) that signals the client to drop its impersonation state.E_IMPERSONATION_FORBIDDEN,E_FORBIDDEN.Admin user search
GET /v0/admin/usersperforms a bounded username-prefix search and returns email, tier, and suspension status.Migration batches
POST /v0/admin/migrations/batches/latest-oncestarts a "migrate to latest" batch (dry-run then real-run for each pending migration, in dependency order).GET /v0/admin/migrations/batches/{batchId}polls batch status and progress.POST /v0/admin/migrations/batches/{batchId}/cancelcancels a running batch and force-releases the global migration lease.MigrationBatchResponseschema added;MigrationListResponsegains alatest_batchfield.E_MIGRATION_BATCH_NOT_FOUND,E_MIGRATION_BATCH_RUNNING.Event delivery health
GET /v0/admin/event-healthexposes pending backlog size, oldest-pending age, and the full unresolved dead-letter set.Other new error codes
E_ALREADY_MEMBER,E_GLOBAL_FACET_MUST_BE_PUBLIC,E_INVITATION_NOT_FOUND,E_MEMBER_NOT_FOUND,E_ORG_FORBIDDEN,E_ORG_LAST_ADMIN,E_ORG_NAME_RESERVED,E_ORG_NAME_TAKEN,E_ORG_NOT_FOUND,E_PRIVATE_FACET_ENTITLEMENT_REQUIRED.Verification
CI — this is a codegen refresh with no hand-written logic.
Summary by CodeRabbit